package com.jackchen.util;

import static java.util.Calendar.HOUR_OF_DAY;
import static java.util.Calendar.MILLISECOND;
import static java.util.Calendar.MINUTE;
import static java.util.Calendar.SECOND;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

public class DateUtils {


	/**
	 * 默认的日期格式化样式
	 */
	public static final String DAY_PATTERN = "yyyy-MM-dd";
	/**
	 * 日期格式化1
	 */
	public static final String DAY_PATTERN1 = "yyyy/MM/dd";
	
	/**
	 * 默认的时间格式化样式
	 */
	public static final String TIME_PATTERN = "HH:mm:ss";

	
    /**
     * 时间格式1（"yyyy-MM-dd HH:mm:ss"）
     */
	public static final String DATE_PATTERN1 = "yyyy-MM-dd HH:mm:ss";	



	/**
	 * 18 位的 yyyyMMddHHmmss.SSS 格式的日期字符串.
	 */
	public static final String DATE_PATTERN2="yyyyMMddHHmmss.SSS";
	/**
	 * 将日期转换为 14 位的字符串(格式为yyyyMMddHHmmss).
	 */
	public static final String DATE_PATTERN3="yyyyMMddHHmmss.SS";
	
	/***
	 * 将日期转换为中文表示方式的字符串(格式为 yyyy年MM月dd日 HH:mm:ss).
	 */
	public static final String DATE_PATTERN4="yyyy年MM月dd日 HH:mm:ss";
	
	
	/**
	 * 将Date格式化成符合默认格式的字符串 默认的日期格式化样式 "yyyy-MM-dd" 默认的时间格式化样式 "HH:mm:ss"
	 * 
	 * @return 返回样例:2012-03-29 14:32:23
	 */
	public static String format(Date date) {
		SimpleDateFormat formatTool = new SimpleDateFormat();
		//formatTool.applyPattern("yyyy-MM-dd" + " " + "HH:mm:ss");
		formatTool.applyPattern(DAY_PATTERN+TIME_PATTERN);
		return formatTool.format(date);
	}

	// ==============================================================================
	// 数据库日期
	// ==============================================================================

	/**
	 * 格式化日期到 Mysql 数据库日期格式字符串的显示.
	 * 
	 * @return - String 格式化后的时间
	 */
	public static String formatDateToMysqlString(java.util.Date date) {
		if (date == null) {
			return "";
		}
		//SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		SimpleDateFormat dateformat = new SimpleDateFormat(DATE_PATTERN1);
		return dateformat.format(date);

	}

	/**
	 * 将 Mysql 数据库日期格式字符串转换为日期.
	 * 
	 * @param input
	 * @return
	 */
	public static Date parseStringToMysqlDate(String input) {
		SimpleDateFormat dateformat = new SimpleDateFormat(
				DATE_PATTERN1);

		try {
			return dateformat.parse(input);
		} catch (ParseException e) {
			e.printStackTrace();
		}

		return null;
	}

	// ----------------------------------------------------------------------------
		//                        字符串转化日期
		// ----------------------------------------------------------------------------
		/**
		 * 按照pattern格式格式化Date
		 * 
		 * @param date
		 * @param pattern
		 *            样例: yyyy/MM/dd
		 * @return 返回样例:2012/03/29
		 */
	public static String format(Date date, String pattern) {
		SimpleDateFormat formatTool = new SimpleDateFormat();
		formatTool.applyPattern(pattern);
		return formatTool.format(date);
	}

	/**
	 * 将符合默认格式的字符串转换成Date
	 * 
	 * @param dateValue
	 * @return     DAY_PATTERN ="yyyy-MM-dd"   
	 * TIME_PATTERN ="HH:mm:ss"
	 * @throws ParseException
	 */
	public static Date parse(String dateValue) throws ParseException {
		SimpleDateFormat formatTool = new SimpleDateFormat();
		formatTool.applyPattern(DAY_PATTERN + " " + TIME_PATTERN);
		return formatTool.parse(dateValue);
	}

	/**
	 * 将符合默认格式的日期字符串转换成Date
	 * 
	 * @param dateValue
	 *            样例:2012-03-29
	 * @return
	 * @throws ParseException
	 */
	public static Date parseDate(String dateValue) throws ParseException {
		SimpleDateFormat formatTool = new SimpleDateFormat();
		formatTool.applyPattern(DAY_PATTERN);
		return formatTool.parse(dateValue);
	}

	/**
	 * 将符合pattern格式的dateValue转换成Date
	 * 
	 * @param dateValue
	 *            样例:2012/03/29
	 * @param pattern
	 *            样例:yyyy/MM/dd
	 * @return
	 * @throws ParseException
	 */
	public static Date parse(String dateValue, String pattern)
			throws ParseException {
		SimpleDateFormat formatTool = new SimpleDateFormat();
		formatTool.applyPattern(pattern);
		return formatTool.parse(dateValue);
	}

	// -------------------------------------------------------------------
		//                     日期转换成字符串
		// -------------------------------------------------------------------
		/**
		 * 将日期转换为中文表示方式的字符串(格式为 yyyy年MM月dd日 HH:mm:ss).
		 */
	public static String dateToChineseString(Date date) {
		if (date == null) {
			return null;
		}

		SimpleDateFormat dateformat = new SimpleDateFormat(
				DATE_PATTERN4);

		return dateformat.format(date);
	}

	/**
	 * 得到格式化后的系统当前日期
	 * 
	 * @param strScheme
	 *            格式模式字符串
	 * @return 格式化后的系统当前时间，如果有异常产生，返回空串""
	 * @see
	 */
	public static final String getNowDateTime(String strScheme) {
		String strReturn = null;
		Date now = new Date();
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(strScheme);
			strReturn = sdf.format(now);
		} catch (Exception e) {
			strReturn = "";
		}
		return strReturn;
	}

	public static final String getNowDateTime() {
		String strReturn = null;
		Date now = new Date();
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(DATE_PATTERN2);
			strReturn = sdf.format(now);
		} catch (Exception e) {
			strReturn = "";
		}
		return strReturn;
	}

	/**
	 * 返回这一天的最早的时候
	 * 
	 * @param date
	 * @return
	 */
	public static Date getEarliest(Date date) {
		return parseTime(date, 0, 0, 0, 0);
	}

	/**
	 * 返回这一天的最晚时候
	 * 
	 * @param date
	 * @return
	 */
	public static Date getLastest(Date date) {
		return parseTime(date, 23, 59, 59, 999);
	}

	/**
	 * 得到指定月的天数
	 * 
	 * @param year
	 * @param month
	 * @return
	 */
	public static int getMonthLastDay(int year, int month) {
		Calendar a = Calendar.getInstance();
		a.set(Calendar.YEAR, year);
		a.set(Calendar.MONTH, month - 1);
		a.set(Calendar.DATE, 1);// 把日期设置为当月第一天
		a.roll(Calendar.DATE, -1);// 日期回滚一天，也就是最后一天
		int maxDate = a.get(Calendar.DATE);
		return maxDate;
	}

	/**
	 * 返回指定时间加上num天后的时间
	 * 
	 * @param date
	 * @param num
	 * @return
	 */
	public static Date add(Date date, int num) {
		Calendar a = Calendar.getInstance();
		a.setTime(date);
		a.add(Calendar.DAY_OF_MONTH, num);
		return a.getTime();
	}

	
	/**
	 * 返回指定时间加上nMinutes秒后的时间
	 * 
	 * @param date
	 * @param num
	 * @return
	 */
	public static Date addMinutes(Date date, int nMinutes) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.MINUTE, nMinutes);
		return c.getTime();
	}
	
	/**
	 * 返回false：date=null，date是1970年；其它都返回true
	 * 
	 * @param date
	 * @return
	 */
	public static boolean isNotEmpty(Date date) {
		if (date != null) {
			Calendar a = Calendar.getInstance();
			a.setTime(date);
			return a.get(Calendar.YEAR) != 1970;
		}
		return Boolean.FALSE;
	}

	/**
	 * 获得date的小时数0-23
	 * 
	 * @param date
	 * @return
	 */
	public static int getHours(Date date) {
		Calendar a = Calendar.getInstance();
		a.setTime(date);
		return a.get(Calendar.HOUR_OF_DAY);
	}

	/**
	 * 获得date是一周的第几天，注意：周日 返回 1，周六 返回 7
	 * 
	 * @param date
	 * @return
	 */
	public static int getDay(Date date) {
		Calendar a = Calendar.getInstance();
		a.setTime(date);
		return a.get(Calendar.DAY_OF_WEEK);
	}

	// ==============================================================================
		//                       设定时间
		// ==============================================================================
		/**
		 * 设定date的时间细节
		 * 
		 * @param date
		 *            要设定时间细节的date
		 * @param hourOfDay
		 *            0-23
		 * @param minute
		 *            0-59
		 * @param second
		 *            0-59
		 * @param milliSecond
		 *            0-999
		 * @return
		 */
	public static Date parseTime(Date date, int hourOfDay, int minute,
			int second, int milliSecond) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		setCalendarTime(cal, hourOfDay, minute, second, milliSecond);
		return cal.getTime();
	}

	/**
	 * 设定date的时间细节
	 * 
	 * @param date
	 *            要设定时间细节的date
	 * @param timeDetail
	 *            以:号分隔的24小时制的时间，例:16:23:42:267 或 16(等同于16:00:00:000)
	 * @return
	 */
	public static Date parseTime(Date date, String timeDetail) {

		List<String> strList = new ArrayList<String>();
		strList.addAll(Arrays.asList(timeDetail.split(":")));

		while (strList.size() < 4) {
			strList.add("0");
		}
		return parseTime(date, Integer.parseInt(strList.get(0)),
				Integer.parseInt(strList.get(1)),
				Integer.parseInt(strList.get(2)),
				Integer.parseInt(strList.get(3)));
	}

	/**
	 * method diffdate 计算两个日期间相隔的日子
	 * 
	 * @param beforDate
	 *            格式:2005-06-20
	 * @param afterDate
	 *            格式:2005-06-21
	 * @return
	 */
	public static int diffDate(String beforeDate, String afterDate) {
		String[] tt = beforeDate.split("-");
		Date firstDate = new Date(Integer.parseInt(tt[0]),
				Integer.parseInt(tt[1]) - 1, Integer.parseInt(tt[2]));

		tt = afterDate.split("-");
		Date nextDate = new Date(Integer.parseInt(tt[0]),
				Integer.parseInt(tt[1]) - 1, Integer.parseInt(tt[2]));
		return (int) (nextDate.getTime() - firstDate.getTime())
				/ (24 * 60 * 60 * 1000);
	}

	/**
	 * 指定时间 是否在 当前时间 之后，注：和日期无关
	 * 
	 * @param time
	 *            指定的时间， 传入样例:16:23:42:267 或 16(等同于16:00:00:000)
	 * @return
	 */
	public static boolean isAfterTime(String time) {
		Date date = parseTime(new Date(), time);
		return date.after(new Date());
	}

	/**
	 * 指定时间 是否在 当前时间 之前，注：和日期无关
	 * 
	 * @param time
	 *            指定的时间， 传入样例:16:23:42:267 或 16(等同于16:00:00:000)
	 * @return
	 */
	public static boolean isBeforeTime(String time) {
		Date date = parseTime(new Date(), time);
		return date.before(new Date());
	}

	private static void setCalendarTime(Calendar cal, int hourOfDay,
			int minute, int second, int milliSecond) {
		cal.set(HOUR_OF_DAY, hourOfDay);
		cal.set(MINUTE, minute);
		cal.set(SECOND, second);
		cal.set(MILLISECOND, milliSecond);
	}

	/**
	 * 得到当前时间，用于文件名，没有特殊字符，使用yyyyMMddHHmmss格式
	 * 
	 * @param afterDay
	 * @return by tim
	 */
	public static String getNowForFileName(int afterDay) {
		GregorianCalendar calendar = new GregorianCalendar();
		// Date date = calendar.getTime();

		SimpleDateFormat df = new SimpleDateFormat(DATE_PATTERN3);

		calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + afterDay);
		Date date = calendar.getTime();

		return df.format(date);
	}


	// -------------------------------------------------------------------------
	// 日期转换18/14位字符串
	// -------------------------------------------------------------------------

	/**
	 * 生成一个 18 位的 yyyyMMddHHmmss.SSS 格式的日期字符串.
	 * 
	 * @param date
	 *            Date
	 * @return String
	 */
	public static String genTimeStampString(Date date) {
		SimpleDateFormat df = new SimpleDateFormat(DATE_PATTERN2);
		return df.format(date);
	}

	/**
	 * 将日期转换为 14 位的字符串(格式为yyyyMMddHHmmss).
	 */

	public static String dateTo14String(Date date) {
		if (date == null) {
			return null;
		}

		SimpleDateFormat dateformat = new SimpleDateFormat(DATE_PATTERN3);

		return dateformat.format(date);
	}

	/***
	 * 计算是否是季度末
	 * 
	 * @param date
	 * @return
	 */
	public static boolean isSeason(String date) {
		int getMonth = Integer.parseInt(date.substring(5, 7));
		boolean sign = false;
		if (getMonth == 3)
			sign = true;
		if (getMonth == 6)
			sign = true;
		if (getMonth == 9)
			sign = true;
		if (getMonth == 12)
			sign = true;
		return sign;
	}

	/**
	 * 获取今天的日期的字符串
	 * 
	 * @return
	 */
	public static String getToday() {
		Calendar cld = Calendar.getInstance();
		java.util.Date date = new Date();
		cld.setTime(date);
		int intMon = cld.get(Calendar.MONTH) + 1;
		int intDay = cld.get(Calendar.DAY_OF_MONTH);
		String mons = String.valueOf(intMon);
		String days = String.valueOf(intDay);
		if (intMon < 10)
			mons = "0" + String.valueOf(intMon);
		if (intDay < 10)
			days = "0" + String.valueOf(intDay);
		return String.valueOf(cld.get(Calendar.YEAR)) + "-" + mons + "-" + days;
	}

	/**
	 * 获取当前月份
	 * 
	 * @return 返回字符串 格式：两位数
	 */
	public static String getCurrentMonth() {
		String strmonth = null;
		Calendar cld = Calendar.getInstance();
		java.util.Date date = new Date();
		cld.setTime(date);
		int intMon = cld.get(Calendar.MONTH) + 1;
		if (intMon < 10)
			strmonth = "0" + String.valueOf(intMon);
		else
			strmonth = String.valueOf(intMon);
		date = null;
		return strmonth;
	}

	public static String getCurrMonth() {
		Calendar cld = Calendar.getInstance();
		java.util.Date date = new Date();
		cld.setTime(date);
		int intMon = cld.get(Calendar.MONTH) + 1;

		return String.valueOf(intMon).toString();
	}

	/**
	 * 获取昨天的日期的字符串
	 */
	public static String getYestoday() {
		Calendar cld = Calendar.getInstance();
		java.util.Date date = new Date();
		cld.setTime(date);
		cld.add(Calendar.DATE, -1);
		int intMon = cld.get(Calendar.MONTH) + 1;
		int intDay = cld.get(Calendar.DAY_OF_MONTH);
		String mons = String.valueOf(intMon);
		String days = String.valueOf(intDay);
		if (intMon < 10)
			mons = "0" + String.valueOf(intMon);
		if (intDay < 10)
			days = "0" + String.valueOf(intDay);
		return String.valueOf(cld.get(Calendar.YEAR)) + "-" + mons + "-" + days;
	}

}
